/*
 * 
 * 
 * 
 */
package com.hboxs.asl.entity;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
import java.util.*;

import static javax.persistence.CascadeType.REMOVE;

/**
 * Entity - 商品分类
 */
@Entity
@Table(name = "xx_product_category")
@SequenceGenerator(name = "sequenceGenerator", sequenceName = "xx_product_category_sequence")
public class ProductCategory extends OrderEntity {

    private static final long serialVersionUID = 5095521437302782717L;

    public ProductCategory() {
    }

    public ProductCategory(String name, String seoTitle, String seoKeywords, String seoDescription, String image, String treePath, Integer grade, ProductCategory parent, Set<ProductCategory> children, Set<Product> products, Set<Brand> brands, Set<ParameterGroup> parameterGroups, Set<Attribute> attributes, Set<Promotion> promotions) {
        this.name = name;
        this.seoTitle = seoTitle;
        this.seoKeywords = seoKeywords;
        this.seoDescription = seoDescription;
        this.image = image;
        this.treePath = treePath;
        this.grade = grade;
        this.parent = parent;
        this.children = children;
        this.products = products;
        this.brands = brands;
        this.parameterGroups = parameterGroups;
        this.attributes = attributes;
        this.promotions = promotions;
    }

    /**
     * 树路径分隔符
     */
    public static final String TREE_PATH_SEPARATOR = ",";

    /**
     * 访问路径前缀
     */
    private static final String PATH_PREFIX = "/p/l";

    /**
     * 访问路径后缀
     */
    private static final String PATH_SUFFIX = ".htm";

    /**
     * 名称
     */
    private String name;

    /**
     * 广告跳转关联
     */
    private Set<Ad> ads = new HashSet<>();

    /**
     * 页面标题
     */
    private String seoTitle;

    /**
     * 页面关键词
     */
    private String seoKeywords;

    /**
     * 页面描述
     */
    private String seoDescription;

    /**
     * 图片
     */
    private String image;

    /**
     * 树路径
     */
    private String treePath;

    /**
     * 层级
     */
    private Integer grade;

    /**
     * 上级分类
     */
    private ProductCategory parent;

    /**
     * 下级分类
     */
    private Set<ProductCategory> children = new HashSet<ProductCategory>();

    /**
     * 商品
     */
    private Set<Product> products = new HashSet<Product>();

    /**
     * 筛选品牌
     */
    private Set<Brand> brands = new HashSet<Brand>();
    
    /**
     * 参数组
     */
    private Set<ParameterGroup> parameterGroups = new HashSet<ParameterGroup>();

    /**
     * 筛选属性
     */
    private Set<Attribute> attributes = new HashSet<Attribute>();

    /**
     * 促销
     */
    private Set<Promotion> promotions = new HashSet<Promotion>();

    /**
     * 优惠卷
     */
    private Set<Coupon> coupons = new HashSet<>();

    /**
     * 是否置顶首页
     */
    private Boolean isTop;

    /**
     * 获取是否置顶
     *
     * @return 是否置顶
     */
    public Boolean getIsTop() {
        return isTop;
    }

    /**
     * 设置是否置顶
     *
     * @param isTop 是否置顶
     */
    public void setIsTop(Boolean isTop) {
        this.isTop = isTop;
    }

    /**
     * 获取名称
     *
     * @return 名称
     */
    @JsonProperty
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = false)
    public String getName() {
        return name;
    }

    /**
     * 设置名称
     *
     * @param name 名称
     */
    public void setName(String name) {
        this.name = name;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    /**
     * 获取页面标题
     *
     * @return 页面标题
     */
    @Length(max = 200)
    public String getSeoTitle() {
        return seoTitle;
    }

    /**
     * 设置页面标题
     *
     * @param seoTitle 页面标题
     */
    public void setSeoTitle(String seoTitle) {
        this.seoTitle = seoTitle;
    }

    /**
     * 获取页面关键词
     *
     * @return 页面关键词
     */
    @Length(max = 200)
    public String getSeoKeywords() {
        return seoKeywords;
    }

    /**
     * 设置页面关键词
     *
     * @param seoKeywords 页面关键词
     */
    public void setSeoKeywords(String seoKeywords) {
        this.seoKeywords = seoKeywords;
    }

    /**
     * 获取页面描述
     *
     * @return 页面描述
     */
    @Length(max = 200)
    public String getSeoDescription() {
        return seoDescription;
    }

    /**
     * 设置页面描述
     *
     * @param seoDescription 页面描述
     */
    public void setSeoDescription(String seoDescription) {
        this.seoDescription = seoDescription;
    }

    /**
     * 获取树路径
     *
     * @return 树路径
     */
    @Column(nullable = false)
    public String getTreePath() {
        return treePath;
    }

    /**
     * 设置树路径
     *
     * @param treePath 树路径
     */
    public void setTreePath(String treePath) {
        this.treePath = treePath;
    }

    /**
     * 获取层级
     *
     * @return 层级
     */
    @Column(nullable = false)
    public Integer getGrade() {
        return grade;
    }

    /**
     * 设置层级
     *
     * @param grade 层级
     */
    public void setGrade(Integer grade) {
        this.grade = grade;
    }

    /**
     * 获取上级分类
     *
     * @return 上级分类
     */
    @ManyToOne(fetch = FetchType.LAZY)
    public ProductCategory getParent() {
        return parent;
    }

    /**
     * 设置上级分类
     * @param parent 上级分类
     */
    public void setParent(ProductCategory parent) {
        this.parent = parent;
    }

    /**
     * 获取下级分类
     *
     * @return 下级分类
     */
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    @OrderBy("order asc")
    public Set<ProductCategory> getChildren() {
        return children;
    }

    /**
     * 设置下级分类
     *
     * @param children 下级分类
     */
    public void setChildren(Set<ProductCategory> children) {
        this.children = children;
    }

    /**
     * 获取商品
     *
     * @return 商品
     */
    @OneToMany(mappedBy = "productCategory", fetch = FetchType.LAZY)
    public Set<Product> getProducts() {
        return products;
    }

    /**
     * 设置商品
     *
     * @param products 商品
     */
    public void setProducts(Set<Product> products) {
        this.products = products;
    }

    /**
     * 获取筛选品牌
     *
     * @return 筛选品牌
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "xx_product_category_brand")
    @OrderBy("order asc")
    public Set<Brand> getBrands() {
        return brands;
    }

    /**
     * 设置筛选品牌
     *
     * @param brands 筛选品牌
     */
    public void setBrands(Set<Brand> brands) {
        this.brands = brands;
    }

	/**
     * 获取参数组
     *
     * @return 参数组
     */
    @OneToMany(mappedBy = "productCategory", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("order asc")
    public Set<ParameterGroup> getParameterGroups() {
        return parameterGroups;
    }

    /**
     * 设置参数组
     *
     * @param parameterGroups 参数组
     */
    public void setParameterGroups(Set<ParameterGroup> parameterGroups) {
        this.parameterGroups = parameterGroups;
    }

    /**
     * 获取筛选属性
     *
     * @return 筛选属性
     */
    @OneToMany(mappedBy = "productCategory", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("order asc")
    public Set<Attribute> getAttributes() {
        return attributes;
    }

    /**
     * 设置筛选属性
     *
     * @param attributes 筛选属性
     */
    public void setAttributes(Set<Attribute> attributes) {
        this.attributes = attributes;
    }

    /**
     * 获取促销
     *
     * @return 促销
     */
    @ManyToMany(mappedBy = "productCategories", fetch = FetchType.LAZY)
    public Set<Promotion> getPromotions() {
        return promotions;
    }

    /**
     * 设置促销
     *
     * @param promotions 促销
     */
    public void setPromotions(Set<Promotion> promotions) {
        this.promotions = promotions;
    }

    /**
     * 获取优惠卷
     *
     * @return 优惠卷
     */
    @ManyToMany(mappedBy = "productCategories", fetch = FetchType.LAZY)
    public Set<Coupon> getCoupons() {
        return coupons;
    }

    /**
     * 设置优惠卷
     *
     * @param coupons 优惠卷
     */
    public void setCoupons(Set<Coupon> coupons) {
        this.coupons = coupons;
    }

    /**
     * 获取树路径
     *
     * @return 树路径
     */
    @Transient
    public List<Long> getTreePaths() {
        List<Long> treePaths = new ArrayList<Long>();
        String[] ids = StringUtils.split(getTreePath(), TREE_PATH_SEPARATOR);
        if (ids != null) {
            for (String id : ids) {
                treePaths.add(Long.valueOf(id));
            }
        }
        return treePaths;
    }

    /**
     * 获取访问路径
     *
     * @return 访问路径
     */
    @Transient
    public String getPath() {
        if (getId() != null) {
            return PATH_PREFIX + PATH_SUFFIX + "?pc=" + getId();
        }
        return null;
    }

    /**
     * 删除前处理
     */
    @PreRemove
    public void preRemove() {
        Set<Promotion> promotions = getPromotions();
        if (promotions != null) {
            for (Promotion promotion : promotions) {
                promotion.getProductCategories().remove(this);
            }
        }
    }


    /**
     * 获取有效促销
     *
     * @return 有效促销
     */
    @Transient
    public Set<Promotion> getValidPromotions() {
        Set<Promotion> allPromotions = new HashSet<Promotion>();
        if (getPromotions() != null) {
            allPromotions.addAll(getPromotions());
        }
        Set<Promotion> validPromotions = new TreeSet<Promotion>();
        for (Promotion promotion : allPromotions) {
            if (promotion != null && promotion.hasBegun() && !promotion.hasEnded() && promotion.getIsUsed()) {
                validPromotions.add(promotion);
            }
        }
        return validPromotions;
    }

    @OneToMany(mappedBy = "productCategory", fetch = FetchType.LAZY, cascade = REMOVE)
    public Set<Ad> getAds() {
        return ads;
    }

    public void setAds(Set<Ad> ads) {
        this.ads = ads;
    }
}